package com.yuanian.timingwheel.model.task.base;

import com.yuanian.timingwheel.model.task.AttachTask;
import com.yuanian.timingwheel.model.task.method.TaskMethod;
import com.yuanian.timingwheel.model.task.executestragy.ExecutionStrategy;
import com.yuanian.timingwheel.model.task.executestragy.RetryExecutionStrategy;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 基础任务
 */
public class BaseTask implements Task {

    //任务ID
    protected Long id;

    //业务ID
    protected String businessId;

    //任务需要执行的方法
    protected TaskMethod taskMethod;

    //任务描述
    protected String taskDesc;

    //执行策略
    protected ExecutionStrategy executionStrategy;

    //具有依赖关系的任务,此任务执行完后再执行
    protected List<AttachTask> attachTaskList;

    //任务信息
    protected TaskExecutionInfo taskExecutionInfo;

    public BaseTask(String businessId, long executionInterval, long executionRounds, Date executionTime, String taskDesc) {
        this.businessId = businessId;
        this.taskExecutionInfo = new TaskExecutionInfo(executionInterval, executionRounds, executionTime);
        this.taskDesc = taskDesc;
    }

    public BaseTask(String businessId, long executionInterval, long executionRounds, long executedRounds, Date executionTime, String taskDesc) {
        this.businessId = businessId;
        this.taskExecutionInfo = new TaskExecutionInfo(executionInterval, executionRounds, executedRounds, executionTime);
        this.taskDesc = taskDesc;
    }

    //任务执行
    public boolean execute() {
        boolean step = false;
        try {
            taskMethod.execute();
            step = true;
            if (attachTaskList != null) {
                for (AttachTask attachTask : attachTaskList) {
                    attachTask.execute();
                }
            }
            getExecutionStrategy().onSuccess();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            if (!step) {
                getExecutionStrategy().onFailure();
            }
            return false;
        }
    }

    @Override
    public ExecutionStrategy getExecutionStrategy() {
        if (executionStrategy == null) {
            executionStrategy = new RetryExecutionStrategy(this);
        }
        return executionStrategy;
    }

    public String getTaskDesc() {
        return taskDesc;
    }

    public void setTaskDesc(String taskDesc) {
        this.taskDesc = taskDesc;
    }

    public void addAttachTask(AttachTask attachTask) {
        if (attachTaskList == null) {
            attachTaskList = new ArrayList<>();
        }
        attachTaskList.add(attachTask);
    }

    public void createTaskMethod(String executionMethod, String beanName, Object[] args) {
        this.taskMethod = new TaskMethod(executionMethod, beanName, args);
    }

    public TaskExecutionInfo getTaskInfo() {
        return taskExecutionInfo;
    }

    public String getBusinessId() {
        return businessId;
    }

    public void setBusinessId(String businessId) {
        this.businessId = businessId;
    }

    public TaskMethod getTaskMethod() {
        return taskMethod;
    }

    public void setTaskMethod(TaskMethod taskMethod) {
        this.taskMethod = taskMethod;
    }

    public void setExecutionStrategy(ExecutionStrategy executionStrategy) {
        this.executionStrategy = executionStrategy;
    }

    public List<AttachTask> getAttachTaskList() {
        return attachTaskList;
    }

    public void setAttachTaskList(List<AttachTask> attachTaskList) {
        this.attachTaskList = attachTaskList;
    }

    public void setTaskInfo(TaskExecutionInfo taskExecutionInfo) {
        this.taskExecutionInfo = taskExecutionInfo;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}
